package com.huabo.controller.interceptor;

import com.huabo.model.OperationLog;
import com.huabo.model.Organization;
import com.huabo.model.Resource;
import com.huabo.model.User;
import com.huabo.service.inter.OperationLogService;
import com.huabo.utils.ApiUtils;
import com.huabo.utils.KeyUtils;
import com.huabo.utils.SpringContextHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 采集日志拦截器
 * Created by Jackie Liu on 2017/7/10.
 */
public class LogInterceptor extends HandlerInterceptorAdapter {

    @Value("${log.open}")
    private boolean logOpen;

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
        if (!logOpen) {
            return;
        }
        String uri = request.getRequestURI();
        Resource resource = getResourceInfo(uri, request);
        if (resource != null) {
            OperationLogService service = SpringContextHelper.getBean(OperationLogService.class);
            OperationLog log = new OperationLog();
            log.setId(KeyUtils.getDistributedId());
            //log.setOperateObject(resource.getOperateObject());
            //log.setTableName(resource.getTableName());
            log.setOperateTime(new Date());
            log.setOperateType(resource.getOperateType());
            log.setRegId(resource.getId());
            log.setResourceUrl(resource.getUrl());
            //log.setFunctionName(resource.getFunctionName());
            log.setTerminalId(getRemoteHost(request));
            log.setOperateCondition(getParamStr(request));
            log.setResourceName(resource.getName());
            log.setResourceCode(resource.getCode());
            User user = ApiUtils.getLoginUser(request);
            if (user != null) {
                Organization org = user.getOrganization();
                log.setOrgCode(org.getCode());
                log.setOrgName(org.getName());
                log.setUserId(user.getId());
                log.setUserName(user.getName());
            }
            service.save(log);
        }
    }

    /**
     * 将request查询参数封装至Map
     *
     * @param request
     * @return
     */
    private static HashMap<String, String> getParameters(HttpServletRequest request) {
        @SuppressWarnings("unchecked")
        Enumeration<String> enume = request.getParameterNames();
        HashMap<String, String> map = new HashMap<String, String>();
        while (enume.hasMoreElements()) {
            String key = enume.nextElement();
            String value = request.getParameter(key);
            map.put(key, value);
        }
        return map;
    }

    private String getParamStr(HttpServletRequest request) {
        HashMap<String, String> params = getParameters(request);
        if (params.size() > 0) {
            StringBuffer sb = new StringBuffer();
            for (Map.Entry<String, String> mapping : params.entrySet()) {
                sb.append("[" + mapping.getKey() + ":" + mapping.getValue() + "]\n");
            }
            return sb.toString();
        }
        return "";
    }

    /**
     * 获取远程客户端Ip
     *
     * @param request
     * @return
     */
    private String getRemoteHost(javax.servlet.http.HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    @SuppressWarnings("unchecked")
    private Resource getResourceInfo(String uri, HttpServletRequest request) {
        List<Resource> list = (List<Resource>) request.getSession().getServletContext().getAttribute("application_resource");
        String url = "";
        Resource resource = null;
        for (Resource res : list) {
            url = res.getUrl();
            if (StringUtils.isNotEmpty(url) && uri.contains(url)) {
                resource = res;
                break;
            }
        }
        return resource;
    }

}
